import redisHandle from './redisHandle'
import app from 'src/app'
import mongodbHandle from './mongodbHandle'
var ObjectId = require('mongodb').ObjectId;
import * as moment from 'moment'
import utils from 'src/serverCore/utils';
import * as schedule from 'node-schedule'
import fighterHandle from 'core/handle/fighterHandle';
import fighterPartnerHandle from 'core/handle/fighterPartnerHandle';
import { PlayerModel } from 'core/model/playerModel';
import Random from 'core/utils/random';
import BattleHandle from 'core/battleHandle/battleHandle';
import arenaHandle from 'core/handle/arenaHandle';
import { FighterTeamInfoModel } from 'core/model/battleInfoModel';

class ArenaAutoHandle {
    async addPlayer(pID) {
        let myData = await mongodbHandle.playerDao.findOne({ _id: ObjectId(pID) })
        if (!myData.cheat) {
            redisHandle.sadd(app.config.gameName + 'arenaAuto', pID)
        }
    }
    init = async () => {
        schedule.scheduleJob('0 1 * * * *', async () => {
            // console.log('自动匹配开始')
            await this.auto()
            // console.log('自动匹配结束')
        });
        //   schedule.scheduleJob('1 * * * * *', async () => {
        //     console.log('自动匹配开始')
        //     await this.auto()
        //     console.log('自动匹配结束')
        // });

        schedule.scheduleJob('0 20 23 * * *', async () => {
            mongodbHandle.arenaDao.remove({ time: { $lte: moment().add(-3, 'day').valueOf() } })
        })
    }

    auto = async () => {
        let smembers = await redisHandle.smembers(app.config.gameName + 'arenaAuto')
        if (smembers) {
            // console.log('自动匹配:', smembers.length)
            for (let i = 0; i < smembers.length; i++) {
                let pID = smembers[i]
                let myData = await mongodbHandle.playerDao.findOne({ _id: ObjectId(pID) })
                if (!myData) {
                    continue
                }
                if (myData.cheat) {
                    continue
                }
                if (i % 200 == 0) {
                    // console.log(i)
                    await utils.setTimeout(50)
                }

                let nowTime = new Date().getTime()
                if (nowTime > (myData.loginTime + 5 * 24 * 60 * 60 * 1000)) {
                    await redisHandle.srem(app.config.gameName + 'arenaAuto', pID)
                    continue;
                }

                myData.arenaAutoTimes = (myData.arenaAutoTimes || 0)
                let arenaAutoTime = myData.arenaAutoTime, dayTime = moment().startOf('day').valueOf()
                if (arenaAutoTime !== dayTime) {
                    myData.arenaAutoTimes = 0
                    myData.arenaAutoTime = dayTime
                }
                if (myData.arenaAutoTimes >= 15) {
                    continue;
                }
                let data = await this.getOpponent(pID, myData)
                if (data && data.opponent) {
                    let opponent = data.opponent
                    let fighterTeamInfo1: FighterTeamInfoModel
                    if (myData.arenaTeam && new Date().getTime() < myData.arenaTeamTime + 259200000) {
                        fighterTeamInfo1 = myData.arenaTeam
                    } else {
                        fighterTeamInfo1 = fighterPartnerHandle.initPartnerFighterTeam(new PlayerModel(myData.playerData))
                    }
                    let fighterTeamInfo2: FighterTeamInfoModel
                    if (opponent.arenaTeam && new Date().getTime() < opponent.arenaTeamTime + 259200000) {
                        fighterTeamInfo2 = opponent.arenaTeam
                    } else {
                        fighterTeamInfo2 = fighterPartnerHandle.initPartnerFighterTeam(new PlayerModel(opponent.playerData))
                    }
                    let team1TID = []
                    fighterTeamInfo1.team.forEach(partner => {
                        if (partner) {
                            team1TID.push(partner.tid)
                        }
                    })
                    let team2TID = []
                    fighterTeamInfo2.team.forEach(partner => {
                        if (partner) {
                            team2TID.push(partner.tid)
                        }
                    })
                    let random = new Random()
                    let seed = random.getSeed()
                    let fighterTeamInfoStr1 = JSON.stringify(fighterTeamInfo1)
                    let fighterTeamInfoStr2 = JSON.stringify(fighterTeamInfo2)
                    let battleHandle = new BattleHandle()
                    await battleHandle.initArenaBattle(fighterTeamInfo1, fighterTeamInfo2, seed)
                    let { result }: any = await battleHandle.start()

                    let { player1Score, player2Score, addScore1, addScore2 } = arenaHandle.calcScore(myData.arenaScore, opponent.arenaScore, result, moment().valueOf())

                    await mongodbHandle.playerDao.updateOne({
                        _id: ObjectId(myData._id),
                    }, {
                        $set: {
                            arenaScore: player1Score,
                            arenaAutoTimes: myData.arenaAutoTimes + 1,
                            arenaAutoTime: myData.arenaAutoTime
                        }
                    })
                    await mongodbHandle.playerDao.updateOne({
                        _id: ObjectId(opponent._id),
                    }, {
                        $set: {
                            arenaScore: player2Score
                        }
                    })
                    await mongodbHandle.arenaDao.newAndSave(myData.name, opponent.name, myData._id.toString(), opponent._id.toString(), fighterTeamInfoStr1, fighterTeamInfoStr2, team1TID, team2TID, Math.floor(addScore1), Math.floor(addScore2), result, seed, app.version, 2)
                }
            }
        }
    }

    getOpponent = async (pID, myData) => {
        let myScore = myData.arenaScore || (100 * 100000000)
        if (myScore < 100000000) {
            myScore = 100 * 100000000
        }
        let maxMatchingScore = myScore * 1.2
        let minMatchingScore = myScore * 0.75
        if (myScore <= 200 * 100000000) {
            maxMatchingScore = myScore * 1.1
            minMatchingScore = myScore * 0.65
        } else if (myScore > 200 * 100000000 && myScore <= 400 * 100000000) {
            maxMatchingScore = myScore * 1.1
            minMatchingScore = myScore * 0.7
        } else if (myScore > 400 * 100000000 && myScore <= 600 * 100000000) {
            maxMatchingScore = myScore * 1.15
            minMatchingScore = myScore * 0.8
        } else if (myScore > 600 * 100000000 && myScore <= 800 * 100000000) {
            maxMatchingScore = myScore * 1.2
            minMatchingScore = myScore * 0.85
        } else if (myScore > 800 * 100000000 && myScore <= 1000 * 100000000) {
            maxMatchingScore = myScore * 1.25
            minMatchingScore = myScore * 0.9
        } else if (myScore > 1000 * 100000000 && myScore <= 1000 * 100000000) {
            maxMatchingScore = 2000 * 100000000
            minMatchingScore = myScore * 0.95
        }
        maxMatchingScore = Math.floor(maxMatchingScore)
        minMatchingScore = Math.floor(minMatchingScore)


        let docs = await mongodbHandle.playerDao.findByPageAndSort({
            currentServerID: myData.currentServerID,
            "cheat": {
                $ne: true
            },
            "arenaScore": {
                $gte: minMatchingScore,
                $lte: maxMatchingScore,
            },
        }, {
            "arenaScore": 1
        }, 0, 100)
        if (docs.length == 0) {
            docs = await mongodbHandle.playerDao.findByPageAndSort({
                currentServerID: myData.currentServerID,
                "cheat": {
                    $ne: true
                },
                "arenaScore": {
                    $gte: myScore,
                },
            }, {
                "arenaScore": 1
            }, 0, 30)
            if (docs.length <= 1) {
                docs = await mongodbHandle.playerDao.findByPageAndSort({
                    currentServerID: myData.currentServerID,
                    "cheat": {
                        $ne: true
                    },
                    "arenaScore": {
                        $lte: myScore,
                    },
                }, {
                    "arenaScore": -1
                }, 0, 10)
            }
        }
        let players: any[] = []
        if (docs && docs.length > 0) {
            for (let i = 0; i < docs.length; i++) {
                let doc = docs[i]
                if (doc._id.toString() !== pID) {
                    players.push(doc)
                }
            }
        }
        if (players.length > 0) {
            let i = Math.floor(Math.random() * players.length)
            return { opponent: players[i], my: myData, delete: false }
        }
        return null
    }
}


let arenaAutoHandle = new ArenaAutoHandle()
export default arenaAutoHandle